﻿using System;
using System.Runtime.InteropServices;

namespace IupNET
{
    public delegate CallbackRes IdleDelegate();

    public static class Iup
    {
        public static void Open()
        {
            Iupc.Open(IntPtr.Zero,IntPtr.Zero);
        }

        public static void Close()
        {
            Iupc.Close();
        }

        public static int MainLoop()
        {
            return Iupc.MainLoop();
        }


        public static int MainLoopLevel()
        {
            return Iupc.MainLoopLevel();
        }

        public static CallbackRes LoopStep()
        {
            return (CallbackRes)Iupc.LoopStep();
        }

        public static void ExitLoop() {
           Iupc.ExitLoop();
        }

        public static void Flush()
        {
            Iupc.Flush();
        }

        private static IdleDelegate idledelegate=null; //gotta store it so garabage collector does not nuke it
        public static IdleDelegate IdleAction {
            set
            {
                idledelegate = value;
                if (idledelegate != null)
                    Iupc.SetFunction("IDLE_ACTION", Marshal.GetFunctionPointerForDelegate(value));
                else
                    Iupc.SetFunction("IDLE_ACTION", IntPtr.Zero);
            }
            get
            {
                return idledelegate;
            }
        }

        public static string Language
        {
            set
            {
                Iupc.SetLanguage(value);
            }
            get
            {
                return Iupc.GetLanguage();
            }
        }

        public static void SetGlobal(string name,string val) {
            Iupc.StoreGlobal(name,val);
        }

        public static string GetGlobal(string name) {
            return Iupc.GetGlobal(name);
        }

        public static string UserName
        {
            get
            {
                return GetGlobal("USERNAME");
            }
        }

       

        public static string Driver
        {
            get
            {
                return GetGlobal("DRIVER");
            }
        }

        public static bool LockLoop
        {
            get
            {
                return GetGlobal("LOCKLOOP") == "YES";
            }
            set
            {
                SetGlobal("LOCKLOOP", value ? "YES" : "NO");
            }
        }

        public static Point2i CursorPos
        {
            get
            {
                return Convert.StringToPoint(GetGlobal("CURSORPOS"));
            }
        }

        public static bool ShiftKey
        {
            get
            {
                return GetGlobal("SHIFTKEY") == "ON";
            }
        }

        public static bool ControlKey
        {
            get
            {
                return GetGlobal("CONTROLKEY") == "ON";
            }
        }


        public static string ModKeyState
        {
            get
            {
                return GetGlobal("MODKEYSTATE");
            }
        }

        public static string System
        {
            get
            {
                return GetGlobal("SYSTEM");
            }
        }

        public static string SystemVersion
        {
            get
            {
                return GetGlobal("SYSTEMVERSION");
            }
        }

        public static string ComputerName
        {
            get
            {
                return GetGlobal("COMPUTERNAME");
            }
        }

        public static Size2i FullSize
        {
            get
            {
                return Convert.StringToSize(GetGlobal("FULLSIZE"));
            }
        }


        public static Size2i ScreenSize
        {
            get
            {
                return Convert.StringToSize(GetGlobal("SCREENSIZE"));
            }
        }


        public static int ScreenDepth
        {
            get
            {
                return Convert.StringToInt(GetGlobal("SCREENDEPTH"));
            }
        }


        public static Color DlgBgColor
        {
            get
            {
                return Convert.StringToColor(GetGlobal("DLGBGCOLOR"));
            }
            set
            {
                SetGlobal("DLGBGCOLOR", Convert.ColorToString(value));
            }
        }

        public static Color DlgFgColor
        {
            get
            {
                return Convert.StringToColor(GetGlobal("DLGFGCOLOR"));
            }
            set
            {
                SetGlobal("DLGFGCOLOR", Convert.ColorToString(value));
            }
        }


        public static Color MenuBgColor
        {
            get
            {
                return Convert.StringToColor(GetGlobal("MENUBGCOLOR"));
            }
            set
            {
                SetGlobal("MENUBGCOLOR", Convert.ColorToString(value));
            }
        }

        public static Color MenuFgColor
        {
            get
            {
                return Convert.StringToColor(GetGlobal("MENUFGCOLOR"));
            }
            set
            {
                SetGlobal("MENUFGCOLOR", Convert.ColorToString(value));
            }
        }


        public static Color TxtBgColor
        {
            get
            {
                return Convert.StringToColor(GetGlobal("TXTBGCOLOR"));
            }
            set
            {
                SetGlobal("TXTBGCOLOR", Convert.ColorToString(value));
            }
        }

        public static Color TxtFgColor
        {
            get
            {
                return Convert.StringToColor(GetGlobal("TXTFGCOLOR"));
            }
            set
            {
                SetGlobal("TXTFGCOLOR", Convert.ColorToString(value));
            }
        }

        public static string DefaultFont
        {
            //TODO: should we have a nice font class?
            get
            {
                return GetGlobal("DEFAULTFONT");
            }
            set
            {
                SetGlobal("DEFAULTFONT", value);
            }
        }


        public static int DefaultFontSize
        {
            //TODO: should we have a nice font class?
            get
            {
                return Convert.StringToInt(GetGlobal("DEFAULTFONTSIZE"));
            }
            set
            {
                SetGlobal("DEFAULTFONTSIZE", value.ToString());
            }
        }

        /// <summary>
        /// Shows a file selection dialog.
        /// Returns 1 for a new file, 0 for an existing file and -1 if canceled.
        /// </summary>
        public static int GetFile(string inname, out string outname)
        {
            outname = inname;
            return Iupc.GetFile(ref outname);
        }

        public static int Alarm(string title, string message, string button1, string button2, string button3)
        {
            return Iupc.Alarm(title, message, button1, button2, button3);
        }

        public static bool GetColor(int x, int y, out Color color)
        {
            byte r = 0, g = 0, b = 0;
            int rs = Iupc.GetColor(x, y, ref r, ref g, ref b);
            color = Color.FromRGB(r, g, b);
            return rs != 0;
        }

        public static bool GetText(string title, ref string text)
        {
            int rs = Iupc.GetText(title, ref text);
            return rs != 0;
        }

        public static int ListDialog(string title, int selected, int max_col, int max_lin, params string[] opts)
        {
            return Iupc.ListDialog(1, title, opts.Length, opts, selected + 1, max_col, max_lin, null);
        }

        public static bool MultiListDialog(string title, int max_col, int max_lin, ref bool[] marks, params string[] opts)
        {
            if (marks.Length != opts.Length)
                throw new Exception("MultiListDialog => length of marks is not same as length of opts");
            int[] m = new int[marks.Length];
            for (int l = 0; l < marks.Length; l++)
            {
                if (marks[l])
                    m[l] = 1;
            }

            int res = Iupc.ListDialog(2, title, opts.Length, opts, 0, max_col, max_lin, m);
            if (res == -1)
                return false;

            for (int l = 0; l < marks.Length; l++)
                marks[l] = m[l] != 0;

            return true;

            //int IupListDialog(int type, const char *title, int size, const char** list, int op, int max_col, int max_lin, int* marks); [in C]

        }

        public static void Message(string title, string message)
        {
            Iupc.Message(title, message);
        }

        public static void Message(string msg)
        {
            Message("", msg);
        }

        public static Control Focused
        {
            get
            {
                return Control.FindControl(Iupc.GetFocus());
            }
        }

    }
}
